﻿//++
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
// Module Name:
//
//  DeleteFolderTask.cs
//    
// Abstract:
//
//  This module implements the DeleteFolderTask class. This handles the task of deleting a folder via EWS.
//
//--

using System;
using System.Diagnostics;
using Microsoft.OfficeCommunicationsServer.Applications.Common;

namespace Microsoft.EnhancedReminders.Scheduler
{
    /// <summary>
    /// This handles the task of deleting a folder via EWS.
    /// </summary>
    internal class DeleteFolderTask : ExchangeTask
    {
        // Folder to be deleted
        private readonly BaseFolderIdType _folderId;

        /// <summary>
        /// ctor
        /// </summary>
        /// <param name="taskContext">Task context</param>
        /// <param name="client">WCF proxy for communicating with EWS</param>
        /// <param name="impersonation">Exchange impersonation info</param>
        /// <param name="emailAddress">E-mail address of the user associated with this request</param>
        /// <param name="folderId">Folder to be deleted</param>
        internal DeleteFolderTask(TaskContext taskContext, ExchangeServicePortType client, ExchangeImpersonationType impersonation, string emailAddress, BaseFolderIdType folderId)
            : base(taskContext, client, impersonation, emailAddress)
        {
            Debug.Assert(folderId != null, "folderId != null");

            _folderId = folderId;
        }

        /// <summary>
        /// Requests that the specified folder is deleted via EWS.
        /// </summary>
        internal override void Begin()
        {
            Logger.WriteTraceVerbose(Context, "DeleteFolderTask.Begin");

            DeleteFolderType deleteFolder = new DeleteFolderType();
            deleteFolder.DeleteType = DisposalType.HardDelete;
            deleteFolder.FolderIds = new BaseFolderIdType[] { _folderId };

            DeleteFolderRequest deleteFolderRequest = new DeleteFolderRequest();
            deleteFolderRequest.DeleteFolder = deleteFolder;
            deleteFolderRequest.ExchangeImpersonation = _impersonation;
            deleteFolderRequest.RequestServerVersion = ExchangeUsers.RequestServerVersion;

            try
            {
                _client.BeginDeleteFolder(deleteFolderRequest, OnDeleteFolderCompleted, null);
            }
            catch (Exception ex)
            {
                HandleAccessError(ex, "BeginDeleteFolder failed.");
            }
        }

        /// <summary>
        /// Handles completion of the EWS request to delete the folder associated with this task.
        /// </summary>
        /// <param name="asyncResult">Status of the asynchronous operation</param>
        private void OnDeleteFolderCompleted(IAsyncResult asyncResult)
        {
            DeleteFolderResponse deleteFolderResponse = GetResponse<DeleteFolderResponse>(asyncResult, _client.EndDeleteFolder, "EndDeleteFolder failed.");

            if (deleteFolderResponse == null)
            {
                return;
            }

            ResponseMessageType responseMessage = deleteFolderResponse.DeleteFolderResponse1.ResponseMessages.Items[0];
            Debug.Assert(responseMessage != null, "responseMessage != null");

            Exception error = null;

            if (responseMessage.ResponseCode == ResponseCodeType.NoError)
            {
                Logger.WriteTraceInformation(Context, "Deleted folder.");
            }
            else if (responseMessage.ResponseCode == ResponseCodeType.ErrorFolderNotFound)
            {
                Logger.WriteTraceInformation(Context, "Tried to delete folder, but it did not exist. Ignoring error.");
            }
            else
            {
                Logger.WriteTraceWarning(Context, "Failed to delete folder.");
                error = new ExchangeTaskFailedException(Context, responseMessage.ResponseCode, "Failed to delete folder.");
            }

            RaiseCompleted(new TaskCompletedEventArgs(_taskContext, error));
        }
    }
}
